package com.company.messagequeue.message;

import com.alibaba.fastjson.JSON;
import org.springframework.util.StringUtils;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * Title: CommonMessage<br>
 * Description: CommonMessage<br>
 * CreateDate:2020年12月04日 15:05
 *
 */
public class CommonMessage {
  /**
   * ip 字符串长度
   */
  private static final int IP_HEX_STRING_LENGTH = 8;
  /**
   * 格式化字符串
   */
  private static final String MESSAGE_FORMAT_STRING = "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t0\r\n";

  /**
   * 分割字符
   */
  private static final String MESSAGE_SUBSTRING_STRING = "\t";

  /**
   * 日期格式化字符串
   */
  private static final String MESSAGE_DATA_FORMAT_STRING = "yyyy/MM/dd HH:mm:ss";

  /**
   * topicid
   */
  private String queueName;
  /**
   * 消息内容
   */
  private Object data;

  /**
   * 消息内容
   */
  private String dataStr;

  /**
   * 创建时间
   */
  private Date createTime;
  /**
   * 消息id
   */
  private String id;
  /**
   * 本地ip
   */
  private byte[] fromIP;

  /**
   * Title: 构造方法方法<br>
   * Description: CommonMessage<br>
   * CreateDate: 2020年12月10日 15:16:42<br>
   *
   * @param queueName
   *          队列名
   * @param data
   *          数据
   * @return
   */
  public CommonMessage(String queueName, Object data) {
    this.id = UUID.randomUUID().toString();
    this.queueName = queueName;
    this.data = data;
    this.createTime = new Date();
    try {
      this.fromIP = InetAddress.getLocalHost().getAddress();
    } catch (UnknownHostException e) {
      e.printStackTrace();
    }
  }

  public CommonMessage() {}

  public String getQueueName() {
    return queueName;
  }

  public void setQueueName(String queueName) {
    this.queueName = queueName;
  }

  public Object getData() {
    return data;
  }

  public void setData(Object data) {
    this.data = data;
  }

  public Date getCreateTime() {
    return createTime;
  }

  public String getId() {
    return id;
  }

  public byte[] getFromIP() {
    return fromIP;
  }

  public void setCreateTime(Date createTime) {
    this.createTime = createTime;
  }

  public void setId(String id) {
    this.id = id;
  }

  public void setFromIP(byte[] fromIP) {
    this.fromIP = fromIP;
  }

  public String getDataStr() {
    return dataStr;
  }

  public void setDataStr(String dataStr) {
    this.dataStr = dataStr;
  }

  public <T> T getData(Class<T> dataClass) {
    return JSON.parseObject(getDataStr(), dataClass);
  }

  @Override
  public String toString() {
    String address = this.fromIP == null ? "000000"
        : parseByteArrayToHex(this.fromIP);

    // 这里的两个空格是.net那边的格式
    return MessageFormat.format(MESSAGE_FORMAT_STRING,
        this.id,
        formatDateToStr(this.createTime),
        this.queueName,
        data.getClass().getName(),
        JSON.toJSONString(data),
        address);
  }

  /**
   * Title: 反序列化程序<br>
   * Description: strToMessage<br>
   * CreateDate: 2020年12月10日 10:54:58<br>
   *
   * @param strData
   *          类型
   * @return CommonMessage
   * @throws Exception
   * @category 反序列化程序
   */
  public static CommonMessage strToMessage(String strData) throws ParseException {
    if (StringUtils.isEmpty(strData)) {
      return null;
    }
    CommonMessage message = new CommonMessage();
    String[] strDataArray = strData.split(MESSAGE_SUBSTRING_STRING);
    message.setId(strDataArray[0]);
    message.setCreateTime(formatStrToDate(strDataArray[1]));
    message.setQueueName(strDataArray[2]);
    message.setFromIP(parseHexStrToByteArray(strDataArray[3]));
    message.setDataStr(strDataArray[4]);
    return message;
  }

  /**
   * Title: 将byte数组转化为16进制字符串<br>
   * Description: 将byte数组转化为16进制字符串<br>
   * CreateDate: 2020年12月04日 17:46:12<br>
   *
   * @param bArr
   *          bArr
   * @return String
   */
  private static String parseByteArrayToHex(byte[] bArr) {
    StringBuffer sb = new StringBuffer(bArr.length * 2);
    String sTmp;

    for (byte aBArr : bArr) {
      sTmp = Integer.toHexString(0xFF & aBArr);
      if (sTmp.length() < 2) {
        sb.append(0);
      }
      sb.append(sTmp.toLowerCase());

    }
    return sb.toString();
  }

  /**
   * Title: 将byte数组转化为16进制字符串<br>
   * Description: 将byte数组转化为16进制字符串<br>
   * CreateDate: 2020年12月04日 17:46:12<br>
   *
   * @param hexStr
   *          16进制字符串
   * @return byte[]
   */
  private static byte[] parseHexStrToByteArray(String hexStr) {
    byte[] result = new byte[IP_HEX_STRING_LENGTH / 2];
    // 如果字符串不为空并且长度是8(一个byte由两个16进制字符串代表,一个ip有四个表示).
    if (!StringUtils.isEmpty(hexStr) && IP_HEX_STRING_LENGTH == hexStr.length()) {
      // 循环每两位处理一次
      for (int i = 0; i <= hexStr.length(); i++) {
        // 如果
        if (i > 0 && i % 2 == 0) {
          result[i / 2 - 1] = Integer.valueOf(hexStr.substring(i - 2, i), 16).byteValue();
        }
      }
      return result;
    }

    return result;
  }

  /**
   * Title: 格式化日期<br>
   * Description: 这里就这两个方法如果引common包里的感觉不太值<br>
   * CreateDate: 2020年12月10日 15:08:15<br>
   *
   * @param dateStr
   *          日期字符串
   * @return java.util.Date
   * @category 格式化日期
   */
  private static Date formatStrToDate(String dateStr) {
    SimpleDateFormat dateTimeSdf = new SimpleDateFormat(CommonMessage.MESSAGE_DATA_FORMAT_STRING);
    Date date = null;
    try {
      date = dateTimeSdf.parse(dateStr);
    } catch (ParseException e) {
      e.printStackTrace();
    }
    return date;
  }

  /**
   * Title: 格式化日期<br>
   * Description: 这里就这两个方法如果引common包里的感觉不太值<br>
   * CreateDate: 2020年12月10日 15:08:15<br>
   *
   * @param date
   *          日期
   * @return java.util.Date
   * @category 格式化日期
   */
  private static String formatDateToStr(Date date) {
    SimpleDateFormat dateTimeSdf = new SimpleDateFormat(CommonMessage.MESSAGE_DATA_FORMAT_STRING);
    return dateTimeSdf.format(date).toString();
  }

}
